/*
 * This file is part of the Code::Blocks IDE and licensed under the GNU Lesser General Public License, version 3
 * http://www.gnu.org/licenses/lgpl-3.0.html
 */

#ifndef CBSTYLEDTEXTCTRL_H_INCLUDED
#define CBSTYLEDTEXTCTRL_H_INCLUDED

#include "../sdk/wxscintilla/include/wx/wxscintilla.h"
#include <wx/longlong.h>
#include "settings.h" // DLLIMPORT

#include <map>
#include <set>

class wxContextMenuEvent;
class wxFocusEvent;
class wxMouseEvent;
class wxPoint;

class DLLIMPORT cbStyledTextCtrl : public wxScintilla
{
    public:
        cbStyledTextCtrl(wxWindow* pParent, int id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 0);
        virtual ~cbStyledTextCtrl();

        /** 别用这个.如果你这样做,它会抛出一个异常. */
        void operator=(const cbStyledTextCtrl& /*rhs*/);

        wxDateTime GetLastFocusTime() const {return m_lastFocusTime;}
        wxString GetLastSelectedText() const {return m_lastSelectedText;}

        void EnableTabSmartJump(bool enable = true);
        /*风格是否被归类为当前语言的字符？*/
        bool IsCharacter(int style);
        /*样式是否被分类为当前语言的字符串？*/
        bool IsString(int style);
        /*样式是否被分类为当前语言的预处理器？*/
        bool IsPreprocessor(int style);
        /*样式是否被分类为当前语言的注释？*/
        bool IsComment(int style);
        /*只有在不通过tab键跳过大括号时才取消调用提示(calltip).*/
        void CallTipCancel();
        /*TODO: 移除?这是未记录的,用户无法预料.(是激活括号快捷键)*/
        bool IsBraceShortcutActive();

        /**
         * 实现功能: 自动完成大括号/引号.
         * 当键入了一个右大括号,但后面还没有右大括号时,请添加一个右大括号.
         * 如果大括号/引号已经是编辑器中的下一个字符,则允许键入要覆盖的大括号/引号.
         * 参数说明: ch参数 键入的最后一个字符.
         */
        void DoBraceCompletion(const wxChar& ch);
        /**
         * 实现功能: 在编辑器中的当前选中(文本)周围加上大括号/引号.
         *
         * 参数说明: ch参数 键入的最后一个字符.
         * 返回值:  如果选择大括号完成适用并编辑了文本,则为True.
         */
        bool DoSelectionBraceCompletion(const wxChar& ch);

        static std::map<int, std::set<int> > &GetCharacterLexerStyles();
        static std::map<int, std::set<int> > &GetStringLexerStyles();
        static std::map<int, std::set<int> > &GetPreprocessorLexerStyles();
        static std::map<int, std::set<int> > &GetCommentLexerStyles();

        /**
         * 实现功能: 滚动最小数量,以便显示参数指定行上方和下方的2行.
         * 参数说明: line 要滚动焦点的行.
         */
        void MakeNearbyLinesVisible(int line);
    private:
        void OnContextMenu(wxContextMenuEvent& event);
        void OnKillFocus(wxFocusEvent& event);
        void OnSetFocus(wxFocusEvent& event);
        void OnMouseMiddleDown(wxMouseEvent& event);
        void OnKeyDown(wxKeyEvent& event);
        void OnKeyUp(wxKeyEvent& event);
        void OnMouseLeftUp(wxMouseEvent& event);

        bool AllowTabSmartJump();
        void HighlightRightBrace();
        void EmulateDwellStart();

        wxWindow* m_pParent;
        wxLongLong m_lastFocusTime;
        int m_bracePosition;
        int m_lastPosition;
        bool m_tabSmartJump;
        wxString m_lastSelectedText;
        bool m_braceShortcutState;

        static std::map<int, std::set<int> > CharacterLexerStyles;
        static std::map<int, std::set<int> > StringLexerStyles;
        static std::map<int, std::set<int> > PreprocessorLexerStyles;
        static std::map<int, std::set<int> > CommentLexerStyles;

        DECLARE_EVENT_TABLE()
};

#endif // CBSTYLEDTEXTCTRL_H_INCLUDED
